﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using System.IO;
using System.Xml;

namespace AMS.UI.Menu
{
    /// <summary>
    /// 生成菜单的基类，封装了从XML的文件到MenuItemInfo菜单对象列表（已授权的列表）的实现。其子类只需要关注具体生成界面元素即可。
    /// </summary>
    public class BaseMenuGenerator : IMainMenu
    {
        /// <summary>
        /// 要创建菜单的窗体
        /// </summary>
        public Form MainForm { get; set; }
        /// <summary>
        /// 菜单控件
        /// </summary>
        public object MenuControl { get; set; }
        /// <summary>
        /// 菜单文件
        /// </summary>
        public string MenuFileName { get; set; }
        /// <summary>
        /// 已授权的项目
        /// </summary>
        protected string[] authorizedItems;

        /// <summary>
        /// 通知对象
        /// </summary>
        public virtual IMenuClickAction MenuClickAction { get; set; }
        /// <summary>
        /// 是否对所有的菜单都授权，如果这个，就不依赖于传进去的授权列表了
        /// </summary>
        public bool AuthorizeToAll { get; set; }

        /// <summary>
        /// 创建菜单
        /// </summary>
        /// <param name="removeExistingItems">是否移出已有的项目</param>
        /// <param name="authorizedItems">授权码</param>
        public virtual void CreateMenu(bool removeExistingItems, string[] authorizedItems)
        {
            this.authorizedItems = authorizedItems;
        }

        /// <summary>
        /// 创建已授权的菜单列表
        /// </summary>
        /// <returns></returns>
        protected List<MenuItemInfo> CreateAuthorizedMenuInfoList()
        {
            XmlDocument xdoc = new XmlDocument();
            xdoc.Load(MenuFileName);
            XmlNodeList nodes = xdoc.SelectNodes("/menu/menuitem");
            List<MenuItemInfo> menus = new List<MenuItemInfo>();
            foreach (XmlNode node in nodes)
            {
                MenuItemInfo item = ConvertXmlNode(node);
                CreateSubMenuInfoList(node, item);
                if (item.IsAuthorized || item.HasSubItems())
                {
                    menus.Add(item);
                }
            }

            return menus;
        }

        /// <summary>
        /// 递归地创建子对象列表
        /// </summary>
        /// <param name="node"></param>
        /// <param name="parentItem"></param>
        private void CreateSubMenuInfoList(XmlNode node, MenuItemInfo parentItem)
        {
            if (node.ChildNodes.Count > 0)
            {
                // 中间节点
                foreach (XmlNode subNode in node.ChildNodes)
                {
                    MenuItemInfo subItem = ConvertXmlNode(subNode);
                    CreateSubMenuInfoList(subNode, subItem);
                    if (subItem.IsAuthorized || subItem.HasSubItems())
                    {
                        parentItem.SubItems.Add(subItem);
                    }
                }
            }
            else
            {
                // 叶子节点
                if (AuthorizeToAll)
                {
                    parentItem.IsAuthorized = true;
                }
                else if (authorizedItems != null && authorizedItems.Length > 0)
                {
                    if (0 <= Array.IndexOf<string>(authorizedItems, parentItem.Name))
                    {
                        parentItem.IsAuthorized = true;
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private MenuItemInfo ConvertXmlNode(XmlNode node)
        {
            MenuItemInfo item = new MenuItemInfo();
            item.Name = GetAttribute(node, "name");
            item.Caption = GetAttribute(node, "caption");
            item.ImageName = GetAttribute(node, "imagename");
            item.ImagePath = GetAttribute(node, "imagepath");
            string isChecked = GetAttribute(node, "checked");
            item.Checked = string.Equals(isChecked, "true") || isChecked == "1";

            return item;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        string GetAttribute(XmlNode node, string attributeName)
        {
            XmlAttribute attribute = node.Attributes[attributeName];
            if (attribute != null)
            {
                return attribute.Value;
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// 菜单的点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void menuItem_Click(object sender, EventArgs e)
        {
            ProcessMenuItemClick(sender);
        }

        /// <summary>
        /// 处理菜单点击事件
        /// </summary>
        /// <param name="sender"></param>
        protected void ProcessMenuItemClick(object sender)
        {
            if (sender == null)
            {
                return;
            }

            bool handled = false;
            MenuClickAction.BeforeProcessMenuClick(sender, ref handled);
            if (!handled)
            {
                MenuClickAction.OnMenuClick(sender);
                MenuClickAction.AfterProcessMenuClick(sender);
            }
        }
    }
}
